package org.mozhu.mboot.core.file.sync;

import com.google.common.collect.Sets;
import org.apache.commons.io.FileUtils;
import org.mozhu.mboot.core.file.cloud.CloudFileService;
import org.mozhu.mboot.core.file.util.PathUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.Collection;
import java.util.Set;

public class FileCloudSyncService {

    private Logger LOGGER = LoggerFactory.getLogger(FileCloudSyncService.class);

    private Set<String> ignoreExtensions = Sets.newHashSet();

    CloudFileService cloudFileService;

    public void syncFile(String key, File file) {
        key = standardFileKey(key);
        LOGGER.info("Sync file [{}], to key[{}]", file.getAbsolutePath(), key);
        cloudFileService.put(key, file);
    }

    protected String standardFileKey(String key) {
        String standardKey = PathUtils.standardize(key);
        if (standardKey.startsWith(PathUtils.SEPARATOR)) {
            return standardKey.substring(1);
        }
        return standardKey;
    }

    public void syncDirectory(String keyPrefix, File directory, String[] extensions) {
        LOGGER.info("Sync directory [{}], to keyPrefix[{}], extensions[{}]", directory.getAbsolutePath(), keyPrefix, extensions);
        Collection<File> files = FileUtils.listFiles(directory, extensions, true);
        for (File file : files) {
            String relativePath = PathUtils.getRelativePath(directory, file);
            if (relativePath == null || needIgnore(relativePath)) {
                continue;
            }
            String key = PathUtils.join(keyPrefix, relativePath);
            syncFile(key, file);
        }
    }

    public void syncDirectory(String keyPrefix, File directory) {
        syncDirectory(keyPrefix, directory, null);
    }

    public void delete(String key) {
        key = standardFileKey(key);
        LOGGER.info("Delete file [{}]", key);
        cloudFileService.delete(key);
    }

    private boolean needIgnore(String relativePath) {
        for (String ignoreExtension : ignoreExtensions) {
            if (relativePath.endsWith(ignoreExtension)) {
                return true;
            }
        }
        return false;
    }

    public void setCloudFileService(CloudFileService cloudFileService) {
        this.cloudFileService = cloudFileService;
    }

    public void setIgnoreExtensions(Set<String> ignoreExtensions) {
        this.ignoreExtensions = ignoreExtensions;
    }
}
